/*
 * Soga.cpp
 *
 *  Created on: 09/10/2013
 *      Author: juliansci
 */
#include <iostream>
#include "Soga.h"
#include "UnidadLogica.h"
#include "../fisica/EntidadFisica.h"
Soga::Soga(double x, double y, double ancho, double alto, string pathImagen) :
		Elemento(x, y, ancho, alto, pathImagen) {
	this->ancho = (ancho * 2) / 3;
	this->alto = (alto * 2) / 3;
	cantClicks = 0;
	this->inicioSoga.first = 0;
	this->inicioSoga.second = 0;
	this->finSoga.first = 0;
	this->finSoga.second = 0;
	this->elementoInicial = NULL;
	this->elementoFinal = NULL;
}
bool Soga::sinReferencias(){
	if(this->elementoInicial == NULL && this->elementoFinal == NULL) return true;
	return false;
}
Soga::~Soga() {
	if (this->elementoInicial)
		this->elementoInicial->eliminarSoga(this);
	if (this->elementoFinal)
		this->elementoFinal->eliminarSoga(this);
}

void Soga::mover(double x, double y) {
	if (this->cantClicks == 0) {
		Elemento::mover(x, y);
		return;
	}
	this->finSoga.first = x;
	this->finSoga.second = y;
}

int Soga::seSuperpone(Elemento* elemento) {
	if (!elemento->aceptaSoga())
		return 2;
	return 1;
}

void Soga::superponer(Elemento* elemento) {
	if (!this->elementoInicial) {
		this->elementoInicial = elemento;
		elemento->agregarSogaInicial(this);
	} else if (!this->elementoFinal) {
		this->elementoFinal = elemento;
		elemento->agregarSogaFinal(this);
	}
}

bool Soga::dejarEnCanvas(double x, double y) {
	cantClicks++;
	if (cantClicks == 2) {
		cantClicks = 2;
		this->finSoga.first = x;
		this->finSoga.second = y;

		return true;
	}
	this->inicioSoga.first = x;
	this->inicioSoga.second = y;
	this->finSoga.first = x;
	this->finSoga.second = y;
	SDL_FreeSurface(surfaceElemento);
	SDL_DestroyTexture(texturaElemento);
	surfaceElemento = NULL;
	texturaElemento = NULL;
	this->pathImagen = "img/sogaEstirada.png";
	return false;
}

void Soga::dibujar(double x, double y, double largo, double ancho,
		SDL_Renderer* renderer) {
	if (this->cantClicks == 0) {
		Elemento::dibujar(x, y, largo, ancho, renderer);
		return;
	}
	if (texturaElemento == NULL) {
		surfaceElemento = IMG_Load(this->pathImagen.c_str());
		texturaElemento = SDL_CreateTextureFromSurface(renderer,
				surfaceElemento);

		if (texturaElemento == NULL) {
			std::cout << "SDL_CreateTextureFromSurface Error: "
					<< SDL_GetError() << std::endl;
			return;
		}
	}
	UnidadLogica* unidadLogica = UnidadLogica::obtenerInstancia();

	double distX = this->finSoga.first - this->inicioSoga.first;
	double distY = this->finSoga.second - this->inicioSoga.second;
	pair<double, double> conversionAnchoyAlto = unidadLogica->convertirULAPixel(
			distX, distY);
	pair<double, double> conversionPosXeY = unidadLogica->convertirULAPixel(
			this->inicioSoga.first, this->inicioSoga.second);

	double angulo = atan2(conversionAnchoyAlto.second,
			conversionAnchoyAlto.first);
	double distancia = sqrt(
			pow(conversionAnchoyAlto.first, 2)
					+ pow(conversionAnchoyAlto.second, 2));
	angulo = (angulo * 180.0);
	angulo = (angulo / 3.14159265);
	if (angulo < 0)
		angulo = 360 + angulo;

	SDL_Rect sdlRect;

	sdlRect.w = distancia;
	sdlRect.h = 5;
	sdlRect.x = conversionPosXeY.first;
	sdlRect.y = conversionPosXeY.second;

	SDL_Point centro;
	centro.x = 0;
	centro.y = 0;
	SDL_RenderCopyEx(renderer, texturaElemento, NULL, &sdlRect, angulo, &centro,
			SDL_FLIP_NONE);
	this->setAnguloRotacion(angulo);
	anchoPixeles = sdlRect.w;
	altoPixeles = sdlRect.h;
	pair<double, double> anchoYAltoUL = unidadLogica->convertirPixelAUL(
			distancia, 10);
	this->setAncho(anchoYAltoUL.first);
	this->setAlto(anchoYAltoUL.second);
	this->setX(this->inicioSoga.first);
	this->setY(this->inicioSoga.second);

}

bool Soga::agregaEnVacio() {
	return false;
}

bool Soga::tieneVertices() {
	return false;
}

void Soga::setPosicionInicial(double x, double y) {
	this->inicioSoga.first = x;
	this->inicioSoga.second = y;
}

void Soga::setPosicionFinal(double x, double y) {
	this->finSoga.first = x;
	this->finSoga.second = y;
}

void Soga::jointearElemento(b2World* world) {
	Elemento* elemento1 = this->obtenerExtremos().first;
	Elemento* elemento2 = this->obtenerExtremos().second;
	if (elemento1->getTipo().compare("balancin")==0){
		EntidadFisica* balancin1 = elemento1->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento1->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			balancin1->agregarEntidadIzquierda(this->getEntidadFisica());
		}
		if (sogaDer == this){
			balancin1->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}
	if (elemento2->getTipo().compare("balancin")==0){
		EntidadFisica* balancin2 = elemento2->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento2->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			balancin2->agregarEntidadIzquierda(this->getEntidadFisica());
		}

		if (sogaDer == this){
			balancin2->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}
	if (elemento1->getTipo().compare("carrito")==0){
		EntidadFisica* carrito1 = elemento1->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento1->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			carrito1->agregarEntidadIzquierda(this->getEntidadFisica());
		}
		if (sogaDer == this){
			carrito1->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}
	if (elemento2->getTipo().compare("carrito")==0){
		EntidadFisica* carrito2 = elemento2->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento2->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			carrito2->agregarEntidadIzquierda(this->getEntidadFisica());
		}

		if (sogaDer == this){
			carrito2->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}

	if (elemento1->getTipo().compare("atijera")==0){
		EntidadFisica* carrito1 = elemento1->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento1->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			carrito1->agregarEntidadIzquierda(this->getEntidadFisica());
		}
		if (sogaDer == this){
			carrito1->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}
	if (elemento2->getTipo().compare("atijera")==0){
		EntidadFisica* carrito2 = elemento2->getEntidadFisica();
		pair<Elemento*,Elemento*> extremosBalancin = elemento2->obtenerExtremos();
		Elemento* sogaIzq = extremosBalancin.first;
		Elemento* sogaDer = extremosBalancin.second;
		if (sogaIzq == this){
			carrito2->agregarEntidadIzquierda(this->getEntidadFisica());
		}

		if (sogaDer == this){
			carrito2->agregarEntidadDerecha(this->getEntidadFisica());
		}
	}

	EntidadFisica* extremo1 =
			this->obtenerExtremos().first->getEntidadFisica();
	EntidadFisica* extremo2 =
			this->obtenerExtremos().second->getEntidadFisica();
	this->getEntidadFisica()->setearElementosAJointear(extremo1, extremo2);
	this->getEntidadFisica()->jointear(world);
}

pair<Elemento*, Elemento*> Soga::obtenerExtremos() {
	pair<Elemento*, Elemento*> extremosSoga;
	extremosSoga.first = this->elementoInicial;
	extremosSoga.second = this->elementoFinal;
	return extremosSoga;

}

pair<double, double> Soga::getPosicionInicial() {
	return this->inicioSoga;
}

pair<double, double> Soga::getPosicionFinal() {
	return this->finSoga;
}

bool Soga::esBasico() {
	return false;
}

void Soga::agregarSogaInicial(Elemento* soga) {
	this->elementoInicial = soga;
}
void Soga::agregarSogaFinal(Elemento* soga) {
	this->elementoFinal = soga;
}

void Soga::inicializarSogaDibujado(double xini, double yini, double xfin,
		double yfin) {
	this->inicioSoga.first = xini;
	this->inicioSoga.second = yini;
	this->finSoga.first = xfin;
	this->finSoga.second = yfin;
	surfaceElemento = NULL;
	texturaElemento = NULL;
	this->pathImagen = "img/sogaEstirada.png";
	this->cantClicks = 2;
}

void Soga::eliminarReferencias(list<Elemento*>* elementosCanvas){

	cout << "BORRO LA SOGA:  " << this<< endl;
	pair<Elemento*, Elemento*> extremosSoga;
	extremosSoga = this->obtenerExtremos();
	cout << "Antes verificacion " << endl;
	if (extremosSoga.first != NULL && extremosSoga.second !=NULL){
		cout << "dentro 1 " << extremosSoga.first->getIdElemento()<< " memeoria: " << extremosSoga.first << endl;
		cout << "dentro 2 " << extremosSoga.second->getIdElemento()<< " memeoria: " << extremosSoga.second << endl;
		extremosSoga.first->eliminarSoga(this);
		extremosSoga.second->eliminarSoga(this);
		cout << "dentrop verificacion " << endl;
		elementosCanvas->remove(this);
		cout << "Despues remover this verificacion " << endl;
	}
}

